home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows 95 / Programming Windows 95.iso / code / CHAP17 / DDEPOP2.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-01  |  6.9 KB  |  227 lines

  1. /*-----------------------------------------------
  2.    DDEPOP2.C -- DDEML Server for Population Data
  3.                 (c) Charles Petzold, 1996
  4.   -----------------------------------------------*/
  5.  
  6. #include <windows.h>
  7. #include <ddeml.h>
  8. #include <string.h>
  9. #include "ddepop.h"
  10.  
  11. #define WM_USER_INITIATE (WM_USER + 1)
  12. #define ID_TIMER         1
  13.  
  14. LRESULT  CALLBACK WndProc     (HWND, UINT, WPARAM, LPARAM) ;
  15. HDDEDATA CALLBACK DdeCallback (UINT, UINT, HCONV, HSZ, HSZ,
  16.                                         HDDEDATA, DWORD, DWORD) ;
  17.  
  18. char      szAppName[] = "DdePop2" ;
  19. char      szTopic[]   = "US_Population" ;
  20. DWORD     idInst ;
  21. HINSTANCE hInst ;
  22. HWND      hwnd ;
  23.  
  24. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  25.                     PSTR szCmdLine, int iCmdShow)
  26.      {
  27.      MSG        msg ;
  28.      WNDCLASSEX wndclass ;
  29.  
  30.      wndclass.cbSize        = sizeof (wndclass) ;
  31.      wndclass.style         = 0 ;
  32.      wndclass.lpfnWndProc   = WndProc ;
  33.      wndclass.cbClsExtra    = 0 ;
  34.      wndclass.cbWndExtra    = 0 ;
  35.      wndclass.hInstance     = hInstance ;
  36.      wndclass.hIcon         = LoadIcon (hInstance, szAppName) ;
  37.      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  38.      wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  39.      wndclass.lpszMenuName  = NULL ;
  40.      wndclass.lpszClassName = szAppName ;
  41.      wndclass.hIconSm       = LoadIcon (hInstance, szAppName) ;
  42.  
  43.      RegisterClassEx (&wndclass) ;
  44.  
  45.      hwnd = CreateWindow (szAppName, "DDEML Population Server",
  46.                           WS_OVERLAPPEDWINDOW,
  47.                           CW_USEDEFAULT, CW_USEDEFAULT,
  48.                           CW_USEDEFAULT, CW_USEDEFAULT,
  49.                           NULL, NULL, hInstance, NULL) ;
  50.  
  51.      ShowWindow (hwnd, SW_SHOWMINNOACTIVE) ;
  52.      UpdateWindow (hwnd) ;
  53.  
  54.                // Initialize for using DDEML
  55.  
  56.      if (DdeInitialize (&idInst, (PFNCALLBACK) &DdeCallback,
  57.                         CBF_FAIL_EXECUTES | CBF_FAIL_POKES |
  58.                         CBF_SKIP_REGISTRATIONS | CBF_SKIP_UNREGISTRATIONS, 0))
  59.           {
  60.           MessageBox (hwnd, "Could not initialize server!",
  61.                       szAppName, MB_ICONEXCLAMATION | MB_OK) ;
  62.  
  63.           DestroyWindow (hwnd) ;
  64.           return FALSE ;
  65.           }
  66.  
  67.                 // Set the timer
  68.  
  69.      SetTimer (hwnd, ID_TIMER, 5000, NULL) ;
  70.  
  71.                // Start things going
  72.  
  73.      SendMessage (hwnd, WM_USER_INITIATE, 0, 0L) ;
  74.  
  75.      while (GetMessage (&msg, NULL, 0, 0))
  76.           {
  77.           TranslateMessage (&msg) ;
  78.           DispatchMessage (&msg) ;
  79.           }
  80.  
  81.                // Clean up
  82.  
  83.      DdeUninitialize (idInst) ;
  84.      KillTimer (hwnd, ID_TIMER) ;
  85.  
  86.      return msg.wParam ;
  87.      }
  88.  
  89. int GetStateNumber (UINT iFmt, HSZ hszItem)
  90.      {
  91.      char szItem[32] ;
  92.      int  i ;
  93.  
  94.      if (iFmt != CF_TEXT)
  95.           return -1 ;
  96.  
  97.      DdeQueryString (idInst, hszItem, szItem, sizeof (szItem), 0) ;
  98.  
  99.      for (i = 0 ; i < NUM_STATES ; i++)
  100.           if (strcmp (szItem, pop[i].szState) == 0)
  101.                break ;
  102.  
  103.      if (i >= NUM_STATES)
  104.           return -1 ;
  105.  
  106.      return i ;
  107.      }
  108.  
  109. HDDEDATA CALLBACK DdeCallback (UINT iType, UINT iFmt, HCONV hConv,
  110.                                HSZ hsz1, HSZ hsz2, HDDEDATA hData,
  111.                                DWORD dwData1, DWORD dwData2)
  112.      {
  113.      char szBuffer[32] ;
  114.      int  i ;
  115.  
  116.      switch (iType)
  117.           {
  118.           case XTYP_CONNECT :            // hsz1 = topic
  119.                                          // hsz2 = service
  120.  
  121.                DdeQueryString (idInst, hsz2, szBuffer, sizeof (szBuffer), 0) ;
  122.  
  123.                if (0 != strcmp (szBuffer, szAppName))
  124.                     return FALSE ;
  125.  
  126.                DdeQueryString (idInst, hsz1, szBuffer, sizeof (szBuffer), 0) ;
  127.  
  128.                if (0 != strcmp (szBuffer, szTopic))
  129.                     return FALSE ;
  130.  
  131.                return (HDDEDATA) TRUE ;
  132.  
  133.           case XTYP_ADVSTART :           // hsz1 = topic
  134.                                          // hsz2 = item
  135.  
  136.                     // Check for matching format and data item
  137.  
  138.                if (-1 == (i = GetStateNumber (iFmt, hsz2)))
  139.                     return FALSE ;
  140.  
  141.                pop[i].lPopLast = 0 ;
  142.                PostMessage (hwnd, WM_TIMER, 0, 0L) ;
  143.  
  144.                return (HDDEDATA) TRUE ;
  145.  
  146.           case XTYP_REQUEST :
  147.           case XTYP_ADVREQ :             // hsz1 = topic
  148.                                          // hsz2 = item
  149.  
  150.                     // Check for matching format and data item
  151.  
  152.                if (-1 == (i = GetStateNumber (iFmt, hsz2)))
  153.                     return NULL ;
  154.  
  155.                wsprintf (szBuffer, "%ld\r\n", pop[i].lPop) ;
  156.  
  157.                return DdeCreateDataHandle (idInst, (unsigned char *) szBuffer,
  158.                                            strlen (szBuffer) + 1,
  159.                                            0, hsz2, CF_TEXT, 0) ;
  160.  
  161.           case XTYP_ADVSTOP :            // hsz1 = topic
  162.                                          // hsz2 = item
  163.   
  164.                     // Check for matching format and data item
  165.  
  166.                if (-1 == (i = GetStateNumber (iFmt, hsz2)))
  167.                     return FALSE ;
  168.  
  169.                return (HDDEDATA) TRUE ;
  170.           }
  171.  
  172.      return NULL ;
  173.      }
  174.  
  175. LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  176.      {
  177.      static HSZ hszService, hszTopic ;
  178.      HSZ        hszItem ;
  179.      int        i ;
  180.  
  181.      switch (iMsg)
  182.           {
  183.           case WM_USER_INITIATE :
  184.                InitPops () ;
  185.  
  186.                hszService = DdeCreateStringHandle (idInst, szAppName, 0) ;
  187.                hszTopic   = DdeCreateStringHandle (idInst, szTopic,   0) ;
  188.  
  189.                DdeNameService (idInst, hszService, NULL, DNS_REGISTER) ;
  190.                return 0 ;
  191.  
  192.           case WM_TIMER :
  193.           case WM_TIMECHANGE :
  194.  
  195.                     // Calculate new current populations
  196.  
  197.                CalcPops () ;
  198.  
  199.                for (i = 0 ; i < NUM_STATES ; i++)
  200.                     if (pop[i].lPop != pop[i].lPopLast)
  201.                          {
  202.                          hszItem = DdeCreateStringHandle (idInst,
  203.                                                           pop[i].szState, 0) ;
  204.  
  205.                          DdePostAdvise (idInst, hszTopic, hszItem) ;
  206.  
  207.                          DdeFreeStringHandle (idInst, hszItem) ;
  208.  
  209.                          pop[i].lPopLast = pop[i].lPop ;
  210.                          }
  211.  
  212.                return 0 ;
  213.  
  214.           case WM_QUERYOPEN :
  215.                return 0 ;
  216.  
  217.           case WM_DESTROY :
  218.                DdeNameService (idInst, hszService, NULL, DNS_UNREGISTER) ;
  219.                DdeFreeStringHandle (idInst, hszService) ;
  220.                DdeFreeStringHandle (idInst, hszTopic) ;
  221.  
  222.                PostQuitMessage (0) ;
  223.                return 0 ;
  224.           }
  225.      return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
  226.      }
  227.